home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-07-14 | 19.8 KB | 659 lines | [TEXT/CWIE] |
- /*/*************************************************************************
- ** Apple Macintosh Developer Technical Support
- **
- ** Macintosh ATA Manager Sample
- **
- ** by Vinne Moscaritolo, <vinnie@apple.com>
- ** Apple Developer Technical Support
- **
- ** Created from as much sample code I could find.
- ** with much help from Gary Wilkinson, Rich Schnell and Martin Minow
- **
- ** " Good Artists Imitate, Great Artist Steal "
- **
- ** File: ATA Demo.c
- **
- ** Copyright © 1996, 1997, 1998 Apple Computer, Inc.
- ** All rights reserved.
- **
- ** Modifications:
- ** 980625 Vin Buffer was still the incorrect size in
- ** DisplayATADriveIdentity routine.
- ** Buffer needs to be 256 words (for 512 bytes long).
- ** Drive identify just assumes you have allocated a
- ** 512 byte buffer and writes it accordingly. In
- ** this case it overwrites the end of the array.
- **
- ** Modified to CW Pro 3 and its headers
- **
- **
- ** 971005 BLoB Buffer was incorrect size in
- ** DisplayATADriveIdentity routine.
- ** Modified to CW Pro 1 and its headers
- ** Added Metrowerks SIOUX specific stuff
- ** Created Fat application
- ** Realized that the words come back swapped;
- ** adjusted for this in the DumpFormatedBuffer routine.
- **
- ** You may incorporate this sample code into your applications without
- ** restriction, though the sample code has been provided "AS IS" and the
- ** responsibility for its operation is 100% yours. However, what you are
- ** not permitted to do is to redistribute the source as "DSC Sample Code"
- ** after having made changes. If you're going to re-distribute the source,
- ** we require that you make it clear in the source that the code was
- ** descended from Apple Sample Code, but that you've made changes.
- **
- **************************************************************************/
-
-
-
- //------------------------------------------------------------------------------------
- #pragma mark Includes
- //------------------------------------------------------------------------------------
- #include <stdio.h>
- #include <stdlib.h>
- #include <ATA.h>
- #ifdef __MWERKS__
- #include <SIOUX.h>
- #endif
- #include "ata_powerpc.h"
- //------------------------------------------------------------------------------------
- #pragma mark Defines
- //------------------------------------------------------------------------------------
-
- //
- // Identifies the bus protocol type.
- //
-
- enum {
- kDevUnknown = 0,
- kDevATA = 1,
- kDevATAPI = 2,
- kDevPCMCIA = 3
- };
-
- //
- // Identifies the Socket type.
- //
- enum {
- kSocketUnknown = 0,
- kSocketInternal = 1,
- kSocketMediaBay = 2,
- kkSocketPCMCIA = 3
- };
-
- //------------------------------------------------------------------------------------
- #pragma mark Macros
- //------------------------------------------------------------------------------------
-
- #define CLEAR(what) do { \
- register Ptr _ptr = (Ptr) &what; \
- register Size _len = sizeof what; \
- for (; _len > 0; --_len) \
- *_ptr++ = 0; \
- } while (0)
-
- #define IF_ERROR(_err_,_str_) if (_err_ != noErr) { printf(_str_); return (_err_); }
-
-
- //------------------------------------------------------------------------------------
- #pragma mark -
-
- //------------------------------------------------------------------------------------
- #pragma mark Identify Drive Info
- //------------------------------------------------------------------------------------
-
- //
- // Bit fields returned from Identify Drive command
- //
- enum {
- magdrv_bit = 15, /* WORD 0: bit number of mag drive indicator */
- rcd_bit = 7, /* WORD 0: bit number of removable indicator */
- fixed_bit = 6, /* WORD 0: bit number of fixed disk indicator */
-
- lbamode_bit = 9, /* bit number of lba support indicator */
- iordy_bit = 11, /* bit number of IORDY support indicator */
- extvalid_bit = 1, /* bit number of valid extension word */
- mode3_bit = 0, /* WORD 64: bit number of mode 3 support */
-
- kMagDrv = 1 << magdrv_bit, /* Bit 15 = 0 -> a magnetic drive */
- kRemovable = 1 << rcd_bit, /* Bit 7 != 0 -> removable cartridge */
- kFixed = 1 << fixed_bit, /* Bit 6 != 0 -> indicates fixed drive */
- kLBAMode = 1 << lbamode_bit, /* LBA support indicator */
- kIORDY = 1 << iordy_bit, /* IORDY support indicator */
- kExtValid = 1 << extvalid_bit, /* Extension word valid */
- MODE3BIT = 1 << mode3_bit /* mode 3 bit in word 64 of ident data */
- };
-
- //
- // This is returned by the device in response to an IDENTIFY command (512 bytes).
- //
- typedef struct IdentifyBlock { /* Structure of Identify data */
- short Signature; /* Word 00: Constant value */
- short NumCyls; /* Word 01: Number of cylinders (default mode) */
- short RSVD0; /* Word 02: Constant value of 0 */
- short NumHds; /* Word 03: Number of heads (default mode) */
- short TrkBytes; /* Word 04: Number of unformatted bytes/track */
- short SecBytes; /* Word 05: Number of unformatted bytes/sector */
- short NumSecs; /* Word 06: Number of sectors/track */
- short VU0; /* Word 07: Vendor unique */
- short VU1; /* Word 08: Vendor unique */
- short VU2; /* Word 09: Vendor unique */
- short Serial[10]; /* Word 10-19: Serial Number (right-justified) */
- short BufType; /* Word 20: Buffer Type */
- short BufSize; /* Word 21: Buffer size in 512 byte increments */
- short NumECC; /* Word 22: Number of ECC bytes */
- short FirmRev[4]; /* Word 23-26: Firmware revision (left-justified) */
- short ModelNum[20]; /* Word 27-46: Model number (left-justified) */
- short MultCmds; /* Word 47: R/W multiple commands not impl = 0 */
- short DblXferFlag; /* Word 48: Double transfer flag */
- short Capabilities; /* Word 49: LBA, DMA, IORDY support indicator */
- short Reserved1; /* Word 50: Reserved */
- short PIOTiming; /* Word 51: PIO transfer timing mode */
- short DMATiming; /* Word 52: DMA transfer timing mode */
- short Extension; /* Word 53: extended info support */
- short CurCylinders; /* Word 54: number of current cylinders */
- short CurHeads; /* Word 55: number of current heads */
- short CurSPT; /* Word 56: number of current sectors per track */
- short CurCapacity[2]; /* Word 57-58: current capacity in sectors */
- short MultSectors; /* Word 59: Multiple sector setting */
- short LBACapacity[2]; /* Word 60-61: total sectors in LBA mode */
- short SWDMA; /* Word 62: single word DMA support */
- short MWDMA; /* Word 63: multi word DMA support */
- short APIOModes; /* Word 64: Advanced PIO Xfr mode supported */
- short MDMATiming; /* Word 65: Minimum Multiword DMA Xfr Cycle */
- short RDMATiming; /* Word 66: Recommended Multiword DMA Cycle */
- short MPIOTiming; /* Word 67: Min PIO XFR Time W/O Flow Control */
- short PIOwRDYTiming; /* Word 68: Min PIO XFR Time with IORDY flow ctrl */
- short Reserved[187]; /* Word 69-255: Reserved */
- } IdentifyBlock;
-
- //
- // The following structure and table simplifies the formatting.
- //
- enum {
- kEndOfTable = 0, /* Marker */
- kDecimal, /* Signed integer (two words are high..low) */
- kHex, /* Bitfield */
- kLeftJust, /* Ascii, left-justified, space padded */
- kRightJust /* Ascii, right-justified, space padded */
- };
- struct FormatTable {
- short firstWord; /* First word in IdentifyBlock cast to short vector */
- short lastWord; /* Last word in IdentifyBlock cast to short vector */
- short format; /* Format from above enum */
- const char *label; /* Text to display */
- };
-
- typedef struct FormatTable FormatTable, *FormatTablePtr;
-
- FormatTable kIdentFormat[] = {
- { 0, 0, kHex, "Configuration word" },
- { 1, 1, kDecimal, "Cylinders" },
- { 3, 3, kDecimal, "Heads" },
- { 4, 4, kDecimal, "Bytes/Track" },
- { 5, 5, kDecimal, "Bytes/Sector (0 = 512 bytes)" },
- { 5, 5, kDecimal, "Sectors/Track" }, /* 35 */
- { 7, 9, kHex, "Vendor Unique (word 7..9)" },
- { 10, 19, kRightJust, "Serial Number" },
- { 20, 20, kHex, "Buffer Type" },
- { 21, 21, kDecimal, "Buffer size in 512 byte increments" },
- { 22, 22, kDecimal, "Number of ECC bytes available" },
- { 23, 26, kLeftJust, "Firmware Revision" },
- { 27, 46, kLeftJust, "Model Number" },
- { 47, 53, kHex, "Capability Flags (word 47..53)" },
- { 54, 54, kDecimal, "Cylinders (current mode)" },
- { 55, 55, kDecimal, "Heads (current mode)" },
- { 56, 56, kDecimal, "Sectors/Track (current mode)" },
- { 57, 58, kDecimal, "Current Capacity in Sectors" },
- { 59, 59, kHex, "Multiple Sector Capability Flag" },
- { 60, 61, kDecimal, "Current User-addressable Sectors" },
- { 62, 62, kHex, "Single Word DMA Transfer Mode Flags" },
- { 63, 63, kHex, "Multiword DMT Transfer Mode Flags" },
- { 0, 0, kEndOfTable,"" }
- };
-
-
-
- //------------------------------------------------------------------------------------
- #pragma mark Prototypes
- //------------------------------------------------------------------------------------
-
- Boolean ATAManagerPresent (void);
- Boolean ATAHardwarePresent (void);
- Boolean TrapAvailable (short theTrap);
- void PrintNumVersion (char *label, NumVersion version );
- OSErr DisplayATAManagerInquiryInfo (void);
-
- OSErr ScanATABusses (void);
- OSErr DisplayATADriveIdentity (UInt32 deviceID );
- void DumpRawBuffer ( UInt8 *bufferPtr, int length );
- void DumpFormatedBuffer (void* p, const FormatTablePtr formatPtr);
- char* DrvrRefToName (short refNum);
-
-
-
- //------------------------------------------------------------------------------------
- #pragma mark -
-
-
- // ---------------------------------------------------------------------------
- void main (void)
- // ---------------------------------------------------------------------------
- {
- OSErr status;
-
- #ifdef __MWERKS__
- SIOUXSettings.asktosaveonclose = false;
- #endif
-
- printf("Macintosh ATA Manager Sample\n\n");
-
- // Check for ATA Hardware
- // you should do this before calling the ATAManager, since some early ROMS
- // could indicate an ATA manager without the proper HW, thus casing a crash.
- if (ATAHardwarePresent() == FALSE) {
- printf("ATA Hardware is not present on this system\n");
- exit(EXIT_FAILURE);
- }
-
- // Check for ATA Manager
- if (ATAManagerPresent() == FALSE) {
- printf("ATA Manager is not present on this system\n");
- exit(EXIT_FAILURE);
- }
-
- // Display ATA Manager Info
- status = DisplayATAManagerInquiryInfo();
- if (status != noErr) {
- printf("Cannot access ATA Manager: %d\n", (int) status);
- exit(EXIT_FAILURE);
- }
-
- // Display ATA Device Info
- status = ScanATABusses();
- if (status != noErr) {
- printf("Cannot access ATA Manager: %d\n", (int) status);
- exit(EXIT_FAILURE);
- }
- }
-
-
- // ---------------------------------------------------------------------------
- OSErr DisplayATAManagerInquiryInfo (void)
- // ---------------------------------------------------------------------------
- //
- // Display information about the ATA Manager
- //
- {
- ataMgrInquiry pb;
- OSErr status;
-
- CLEAR(pb);
-
- pb.ataPBFunctionCode = kATAMgrManagerInquiry;
- pb.ataPBVers = kATAPBVers1;
-
- status = ataManager((ataPB*) &pb );
- IF_ERROR(status, "ATA Manager Inquiry failed\n")
-
- printf("ATA Manager inquiry:\n");
- PrintNumVersion("\tATA Manager Version:", pb.ataMgrVersion);
- printf("\tBusses:\t\t%d\n\tDevices:\t%d\n",
- pb.ataBusCnt, pb.ataDevCnt);
- printf("\tPIO Modes:\t%x\n\tDMA Modes:\t%d\n\tMulti DMA Modes:%x\n",
- pb.ataPioModes, pb.ataSingleDMAModes, pb.ataMultiDMAModes);
- printf("-----------------------------------------\n\n");
- return (status);
- }
-
-
- // ---------------------------------------------------------------------------
- OSErr ScanATABusses (void)
- // ---------------------------------------------------------------------------
- //
- // Display information about the ATA Busses
- //
- {
- ataDrvrRegister pb;
- OSErr status;
-
- // Get first device ID (yes you have to do this once)
- CLEAR(pb);
- pb.ataPBFunctionCode = kATAMgrFindDriverRefnum;
- pb.ataPBVers = kATAPBVers1;
- pb.ataPBDeviceID = (UInt32)0x0000ffff;
- status = ataManager((ataPB*) &pb );
-
- // loop through devices
- for (pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID;
- pb.ataPBDeviceID != 0xff;
- pb.ataPBDeviceID = (UInt32) pb.ataDeviceNextID)
- {
- status = ataManager((ataPB*) &pb );
- IF_ERROR(status, "ATA Find Driver failed\n")
-
- printf("Device %d %#s\n", pb.ataPBDeviceID, DrvrRefToName(pb.ataDrvrRefNum) );
- DisplayATADriveIdentity(pb.ataPBDeviceID);
-
- printf("-----------------------------------------\n\n");
- };
-
- printf("\n");
- return (status);
- }
-
-
-
- // ---------------------------------------------------------------------------
- OSErr DisplayATADriveIdentity (UInt32 deviceID)
- // ---------------------------------------------------------------------------
- //
- // Display information about the ATA Identify Info
- //
- {
- ataIdentify pb;
- ataDevConfiguration pb1;
-
- UInt16 buffer[256];
- OSErr status;
-
-
- // Get Driver Configuration
- CLEAR(pb1);
- pb1.ataPBFunctionCode = kATAMgrGetDrvConfiguration;
- pb1.ataPBVers = kATAPBVers2;
- pb1.ataPBDeviceID = deviceID;
-
- status = ataManager((ataPB*) &pb1 );
- IF_ERROR(status, "ATA GetDrvConfiguration failed\n")
-
-
- // Setup Identify block;
- CLEAR(pb);
- pb.ataPBFunctionCode = kATAMgrDriveIdentify;
- pb.ataPBVers = kATAPBVers1;
- pb.ataPBDeviceID = deviceID;
- pb.ataPBFlags = mATAFlagIORead + mATAFlagByteSwap ;
-
- if(pb1.ataDeviceType == kDevATAPI) pb.ataPBFlags += mATAFlagProtocol1;
-
- pb.ataPBTimeOut = 100;
- pb.ataPBBuffer = (void*) buffer;
-
- status = ataManager((ataPB*) &pb );
- IF_ERROR(status, "ATA DriveIdentify failed\n")
-
- printf("Configuration: (");
-
- switch(pb1.ataDeviceType){
- case kDevUnknown:
- printf("Unknown protocol");
- break;
-
- case kDevATA:
- printf("ATA");
- break;
-
- case kDevATAPI:
- printf("ATAPI");
- break;
-
- case kDevPCMCIA:
- printf("PCMCIA");
- break;
- }
-
- switch(pb1.ataSocketType){
- case kSocketUnknown:
- printf(", Unknown Socket");
- break;
-
- case kSocketInternal:
- printf(", Internal");
- break;
-
- case kSocketMediaBay:
- printf(", Media Bay");
- break;
-
- case kkSocketPCMCIA:
- printf(", PCMCIA, Vcc=%d, Vpp1=%d, Vpp2=%d",
- pb1.atapcVcc, pb1.atapcVpp1,pb1.atapcVpp2);
- break;
- }
-
- printf(")\n");
-
- DumpFormatedBuffer(buffer, kIdentFormat);
- };
-
-
-
-
- // ---------------------------------------------------------------------------
- Boolean ATAManagerPresent (void)
- // ---------------------------------------------------------------------------
- //
- // returns true if this machine has the ata manager
- //
- {
- return (TrapAvailable(kATATrap));
- }
-
- // ---------------------------------------------------------------------------
- Boolean ATAHardwarePresent (void)
- // ---------------------------------------------------------------------------
- //
- // returns true if this machine has ata hardware
- //
- {
- UInt16 configFlags;
-
- // Hardware configuration flags
- configFlags = LMGetHWCfgFlags();
-
- return (configFlags & 0x0080);
- }
-
- //------------------------------------------------------------------------------------
- #pragma mark -
-
- #define NumToolboxTraps() ( \
- (NGetTrapAddress(_InitGraf, ToolTrap) \
- == NGetTrapAddress(0xAA6E, ToolTrap)) \
- ? 0x200 : 0x400 \
- )
- #define GetTrapType(theTrap) ( \
- (((theTrap) & 0x800) != 0) ? ToolTrap : OSTrap \
- )
-
- // ---------------------------------------------------------------------------
- Boolean TrapAvailable (short theTrap)
- // ---------------------------------------------------------------------------
- // (see Inside Mac VI 3-8)
- {
- TrapType trapType;
-
- trapType = GetTrapType(theTrap);
- if (trapType == ToolTrap) {
- theTrap &= 0x07FF;
- if (theTrap >= NumToolboxTraps())
- theTrap = _Unimplemented;
- }
- return (
- NGetTrapAddress(theTrap, trapType)
- != NGetTrapAddress(_Unimplemented, ToolTrap)
- );
- }
-
- // ---------------------------------------------------------------------------
- void PrintNumVersion (char *label, NumVersion version )
- // ---------------------------------------------------------------------------
- //
- // Decode version number info
- //
- {
- char *stage;
-
- switch (version.stage) {
- case developStage: stage = "d"; break;
- case alphaStage: stage = "a"; break;
- case betaStage: stage = "b"; break;
- case finalStage: stage = ""; break;
- default: stage = "?"; break;
-
- }
- printf("%s %d.%d.%d",
- label,
- version.majorRev,
- (version.minorAndBugRev>>4), (version.minorAndBugRev & 0xf),
- stage);
- if(version.stage != finalStage) printf(".%d",version.nonRelRev);
-
- printf(" (hex %08lx)\n", (* ((unsigned long *) &version)));
- }
-
-
-
- // ---------------------------------------------------------------------------
- void DumpFormatedBuffer (void* p, const FormatTablePtr format)
- // ---------------------------------------------------------------------------
- //
- // Dump formatted buffer
- //
-
- {
- unsigned short *idInfo = p;
-
- register char *charField;
- register short fieldLength;
- register short i;
- register long value;
- register FormatTablePtr formatPtr;
-
- #define FORMAT (*formatPtr)
-
- for (formatPtr = format; FORMAT.format != kEndOfTable; formatPtr++) {
- printf("%35s", FORMAT.label);
- switch (FORMAT.format) {
- // Decimal values come as two words with the words swapped.
- case kDecimal:
- value = 0;
- for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
- value <<= 16;
- value += idInfo[i];
- }
- printf(" %lu", value); // was %lu
- break;
- case kHex:
- for (i = FORMAT.lastWord; i >= FORMAT.firstWord; i--) {
- value = idInfo[i];
- printf(" %04ld", value);
- }
- break;
- case kLeftJust:
- charField = (char *) &idInfo[FORMAT.firstWord];
- fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
- * sizeof (unsigned short);
- /*
- * First scan for an unspecified field.
- */
- for (i = 0; i <= fieldLength; i++) {
- if (charField[i] != '\0')
- goto gotLeftJustField;
- }
- printf(" <not specified>");
- break;
- gotLeftJustField:
- for (i = fieldLength; i > 0; --i) {
- if (charField[i - 1] != ' ')
- break;
- }
- printf(" \"%.*s\"", (int) i, charField);
- break;
- case kRightJust:
- charField = (char *) &idInfo[FORMAT.firstWord];
- fieldLength = (FORMAT.lastWord - FORMAT.firstWord + 1)
- * sizeof (unsigned short);
- /*
- * First scan for an unspecified field.
- */
- for (i = 0; i <= fieldLength; i++) {
- if (charField[i] != '\0')
- goto gotRightJustField;
- }
- printf(" <not specified>");
- break;
- gotRightJustField:
- for (i = 0; i < fieldLength; i++) {
- if (charField[i] != ' ')
- break;
- }
- printf(" \"%.*s\"", (int) (fieldLength - i), &charField[i]);
- break;
- }
- printf("\n");
- }
- // DumpRawBuffer( p,512);
- }
-
- // ---------------------------------------------------------------------------
- void DumpRawBuffer ( UInt8 *bufferPtr, int length )
- // ---------------------------------------------------------------------------
- //
- // Dump buffer
- //
-
- {
- register int i;
- int lineStart;
- int lineLength;
- short c;
-
- #define kLineSize 16
- for (lineStart = 0; lineStart < length; lineStart += lineLength) {
- lineLength = kLineSize;
- if (lineStart + lineLength > length)
- lineLength = length - lineStart;
- printf("%03x %3d:", lineStart, lineStart);
- for (i = 0; i < lineLength; i++)
- printf(" %02x", bufferPtr[lineStart + i] & 0xFF);
- for (; i < kLineSize; i++)
- printf(" ");
- printf(" ");
- for (i = 0; i < lineLength; i++) {
- c = bufferPtr[lineStart + i] & 0xFF;
- if (c > ' ' && c < '~')
- printf("%c", c);
- else {
- printf(".");
- }
- }
- printf("\n");
- }
- }
-
-
-
- // ---------------------------------------------------------------------------
- char* DrvrRefToName(short refNum)
- // ---------------------------------------------------------------------------
- //
- // lookup driver name in table
- //
-
- {
- AuxDCEHandle* UTable = (AuxDCEHandle*) LMGetUTableBase();
- DCtlPtr dctl;
- Ptr p;
-
- if(!refNum) return ((char*) "\p<none>");
-
- dctl = (DCtlPtr) *UTable[~refNum];
- p = dctl->dCtlDriver;
- if( dctl->dCtlFlags & 0x0040) p = (void*) *p;
-
- return ( p?(char*) (p+18):(char*)"\p-Purged-");
- }
-